package library;

import java.util.Objects;

public class Book {
    private final BookId id;
    private final String title;
    private final String author;
    private BookStatus status;

    public Book(BookId id, String title, String author) {
        this.id = Objects.requireNonNull(id, "Book id cannot be null");
        this.title = Objects.requireNonNull(title, "Title cannot be null");
        this.author = Objects.requireNonNull(author, "Author cannot be null");
        this.status = BookStatus.AVAILABLE;
    }

    public void borrow() {
        if (status != BookStatus.AVAILABLE) {
            throw new IllegalStateException("Book is not available for borrowing");
        }
        status = BookStatus.BORROWED;
    }

    public void returnBook() {
        if (status != BookStatus.BORROWED) {
            throw new IllegalStateException("Book is not borrowed");
        }
        status = BookStatus.AVAILABLE;
    }

    public boolean isAvailable() {
        return status == BookStatus.AVAILABLE;
    }

    public BookId getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public BookStatus getStatus() {
        return status;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book book = (Book) o;
        return Objects.equals(id, book.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

enum BookStatus {
    AVAILABLE,
    BORROWED
}

// Value Object
class BookId {
    private final String value;

    public BookId(String value) {
        this.value = Objects.requireNonNull(value, "BookId value cannot be null");
    }

    public String getValue() {
        return value;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BookId bookId = (BookId) o;
        return Objects.equals(value, bookId.value);
    }

    @Override
    public int hashCode() {
        return Objects.hash(value);
    }
}
